package com.cl.unipay4j.wx.splitbill;

import com.alibaba.fastjson.JSON;
import com.cl.unipay4j.core.Result;
import com.cl.unipay4j.core.UnipayConst;
import com.cl.unipay4j.core.exception.InvalidParamException;
import com.cl.unipay4j.core.splitbill.BindModel;
import com.cl.unipay4j.core.splitbill.ISplitBillRelationBind;
import com.cl.unipay4j.core.util.EnumUtil;
import com.cl.unipay4j.core.util.StrUtil;
import com.cl.unipay4j.wx.AbstractWxPay;
import com.cl.unipay4j.wx.WxBizEnum;
import com.cl.unipay4j.wx.sdk.WXPayConstants;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信分账接收方绑定类
 *
 * @author siashan
 * @since V1.0.1
 **/
@Slf4j
public class WxPaySplitBillRelationBind extends AbstractWxPay implements ISplitBillRelationBind {

    /**
     * 微信分账接收方绑定
     *
     * @param model       绑定参数
     * @return 绑定结果
     */
    @Override
    public Result bind(BindModel model) {
        log.info("WxPaySplitBill => 订单{} 微信分账接收方绑定请求到达", model.getOutTradeNo());
        try {
            Map<String, String> r = initWxPay().sendRequest(wrapParam(model), WXPayConstants.PAY_PROFITSHARINGADDRECEIVER_URL_SUFFIX, WxBizEnum.SPLITBILL, true);
            log.info("WxPaySplitBill => 订单{} 微信分账接收方绑定请求返回报文:{}", model.getOutTradeNo(), r);
            String returnCode = r.get(WXPayConstants.RETURN_CODE);
            if (UnipayConst.SUCCESS.equals(returnCode)) {
                if (UnipayConst.SUCCESS.equals(r.get(WXPayConstants.RESULT_CODE))) {
                    log.info("WxPaySplitBill => 订单{} 微信分账接收方绑定请求成功", model.getOutTradeNo());
                    return Result.tradeSuccess(r);
                } else {
                    String errCode = r.get(WXPayConstants.ERR_CODE);
                    String errCodeDes = r.get(WXPayConstants.ERR_CODE_DES);
                    log.info("WxPaySplitBill => 订单{} 微信分账接收方绑定请求返回失败,错误代码:{},错误描述:{}", model.getOutTradeNo(), errCode, errCodeDes);
                    return Result.returnFail(errCode, errCodeDes);
                }
            } else {
                String returnMsg = r.get(WXPayConstants.RETURN_MSG);
                log.info("WxPaySplitBill => 订单{} 微信分账接收方绑定请求返回失败,错误代码:{},错误描述:{}", model.getOutTradeNo(), returnCode, returnMsg);
                return Result.returnFail(returnCode, returnMsg);
            }

        } catch (Exception e) {
            log.info("WxPaySplitBill => 订单{} 微信分账接收方绑定请求异常", model.getOutTradeNo());
        }
        return Result.exception();
    }

    /**
     * 封装请求参数
     *
     * @param model   请求体
     * @return 请求参数
     */
    private Map<String, String> wrapParam(BindModel model) {
        Map<String, String> map = new HashMap<>();
        Map<String, String> receiver = new HashMap<>();
        receiver.put("type", model.getType());
        receiver.put("account", model.getAccount());
        receiver.put("name", model.getName());
        String relationType = model.getRelationType();
        checkRelationType(relationType);
        receiver.put("relation_type", relationType);
        if (WxReceiverRelationType.CUSTOM.getValue().equals(relationType)) {
            if (StrUtil.isBlank(model.getCustomRelation())){
                throw  new InvalidParamException("自定义分账关系属性缺失");
            }
            receiver.put("custom_relation", model.getCustomRelation());
        }
        map.put("receiver", JSON.toJSONString(receiver));
        return map;
    }

    /**
     * 校验与分账方的关系类型是否合法
     *
     * @param relationType   关系类型
     */
    private void checkRelationType(String relationType) {
        if (StrUtil.isBlank(relationType)) {
            throw new InvalidParamException("与分账方的关系类型不能为空");
        }
        WxReceiverRelationType wxReceiverRelationType = EnumUtil.getIEnum(WxReceiverRelationType.class, relationType);
        if (null == wxReceiverRelationType) {
            throw new InvalidParamException("与分账方的关系类型不合法");
        }
    }
}
